<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\fetch\ocean;

use app\enum\CommonEnum;
use app\enum\ConfigEnum;
use app\enum\OceanEnum;
use app\model\ClientAccountModel;
use app\model\OeAssetsAppModel;
use app\model\OeAssetsModel;
use app\model\OeTrackUrlModel;
use app\model\OeVideoModel;
use app\service\client\AccountService;
use app\service\fetch\MediaInterface;
use app\service\fetch\MediaService;
use app\service\ocean\AdvertiserService;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Cache;
use think\Model;

class TrackUrlService extends MediaService implements MediaInterface
{
    /**
     * 拉取巨量推广内容数据列表.
     * @param string $advertiserId 广告主id
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getTrackUrl(string $advertiserId = ''): bool
    {
        // 获取账户信息
        $obj = AccountService::getAccountModel(0, $advertiserId);
        if (! $obj instanceof ClientAccountModel || ! $obj->getKey()) {
            return self::setError('账户数据不存在');
        }

        $data = OeAssetsModel::where('advertiser_id', $advertiserId)->select()->toArray();
        foreach ($data as $val) {
            $val['landing_pages'] = json_decode($val['landing_pages'], true);
            if ($val['asset_type'] == 'THIRD_EXTERNAL' && ! empty($val['landing_pages'])) {
                foreach ($val['landing_pages'] as $item) {
                    if (! isset($item['download_url'])) {
                        $item['download_url'] = '';
                    }
                    self::fetchReport($advertiserId, $item);
                }
            }

            $val['app'] = json_decode($val['app'], true);
            if ($val['asset_type'] = 'APP' && ! empty($val['app'])) {
                OeAssetsAppModel::where('advertiser_id', $advertiserId)->delete();
                foreach ($val['app'] as $a) {
                    $a['advertiser_id'] = $advertiserId;
                    $assetsAppModel = self::getAssetsApp($a);
                    if (! $assetsAppModel instanceof OeAssetsAppModel || ! $assetsAppModel->getKey()) {
                        $assetsAppModel = new OeAssetsAppModel();
                    }
                    $assetsAppModel->setAttrs($a);
                    if (! $assetsAppModel->save()) {
                        return self::setError('保存信息出错');
                    }
                    self::fetchReport($advertiserId, $a);
                }
            }
        }

        $redis = Cache::store('redis')->handler();
        $redis->lPush(ConfigEnum::CACHE_CONFIG[OceanEnum::LIST_CONFIG_KEY]['optimized_goal'], $advertiserId);
        return true;
    }

    /**
     * 拉取信息.
     *
     * @param string $advertiserId 账户id
     * @return bool|mixed|string
     */
    private static function getList(string $advertiserId = '', int $assetId = 0, string $downloadUrl = '', int $page = 1)
    {
        $token = AccountService::getToken(CommonEnum::OE_MEDIA, $advertiserId);
        if (! $token) {
            return self::setError('token获取失败');
        }
        $headers = [
            'Access-Token' => $token,
            'Content-Type' => 'application/json',
        ];
        $params = [
            'advertiser_id' => $advertiserId,
            'asset_id' => $assetId,
            'page' => $page,
            'page_size' => 30,
        ];
        if ($downloadUrl) {
            $params['download_url'] = $downloadUrl;
        }
        return AdvertiserService::getTrackUrl($headers, $params);
    }

    /**
     * 获取视频信息.
     *
     * @param string $advertiserId 账户id
     * @return null|array|mixed|Model|OeVideoModel
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private static function getInfo(string $advertiserId = '', int $assetId = 0, array $data = [])
    {
        $where = [
            ['advertiser_id', '=', $advertiserId],
            ['asset_id', '=', $assetId],
            ['track_url_group_id', '=', $data['track_url_group_id']],
        ];

        return (new OeTrackUrlModel())->where($where)->field(true)->find();
    }

    /**
     * @return null|array|mixed|Model|OeAssetsAppModel
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private static function getAssetsApp(array $app = [])
    {
        // 查询是否存在
        $where = [
            ['advertiser_id', '=', $app['advertiser_id']],
            ['app_id', '=', $app['app_id']],
            ['asset_id', '=', $app['asset_id']],
        ];

        if (! empty($app['download_url'])) {
            $where[] = ['download_url', '=', $app['download_url']];
        }

        return (new OeAssetsAppModel())->where($where)->field(true)->find();
    }

    /**
     * 拉取数据.
     * @param string $advertiserId 账户ID
     * @param array $item 数组
     * @return bool|void
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    private static function fetchReport(string $advertiserId = '', array $item = [])
    {
        $page = 0;
        while (true) {
            $result = self::getList($advertiserId, $item['asset_id'], '', ++$page);
            if ($result === false) {
                return false;
            }
            if (empty($result['data']['track_url_groups'])) {
                break;
            }
            $list = $result['data']['track_url_groups'];
            foreach ($list as $l) {
                $model = self::getInfo($advertiserId, intval($item['asset_id']), $l);
                if (! $model instanceof OeTrackUrlModel || ! $model->getKey()) {
                    $model = new OeTrackUrlModel();
                }
                $l['advertiser_id'] = $advertiserId;
                $l['asset_id'] = $item['asset_id'];
                $l['asset_name'] = $item['asset_name'];
                $model->setAttrs($l);
                if (! empty($item['app_id'])) {
                    $model->setAttr('type', OeTrackUrlModel::TYPE_SON);
                }

                if (! $model->save()) {
                    return self::setError('保存信息出错');
                }
            }
        }
    }
}
